package com.nuc.seckill.security.config;

import com.nuc.seckill.base.BaseResponse;
import com.nuc.seckill.entity.Token;
import com.nuc.seckill.exception.ErrorMessage;
import com.nuc.seckill.security.entity.AdminUser;
import com.nuc.seckill.security.exception.BaseAuthenticationException;
import com.nuc.seckill.security.filter.TokenFilter;
import com.nuc.seckill.service.AdminTokenService;
import com.nuc.seckill.utils.CookieUtil;
import com.nuc.seckill.utils.ResponseUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;

import javax.annotation.Resource;


/**
 * @author spider
 */
@Configuration
@Slf4j
public class SecurityHandlerConfig {

    @Resource
    private AdminTokenService adminTokenService;

    /**
     * json登陆成功，返回Token
     *
     * @return org.springframework.security.web.authentication.AuthenticationSuccessHandler
     * @author 石一歌
     * @date 2022/8/9 23:35
     */
    @Bean
    public AuthenticationSuccessHandler jsonLoginSuccessHandler() {
        return (request, response, authentication) -> {
            AdminUser loginUser = (AdminUser) authentication.getPrincipal();
            Token token = adminTokenService.saveToken(loginUser);
            BaseResponse<?> ok = BaseResponse.ok(token);
            ResponseUtil.responseJson(request, response, HttpStatus.OK.value(), ok);
        };
    }

    /**
     * 表单登陆成功
     *
     * @return org.springframework.security.web.authentication.AuthenticationSuccessHandler
     * @author 石一歌
     * @date 2022/8/9 23:36
     */
    @Bean
    public AuthenticationSuccessHandler formLoginSuccessHandler() {
        return (request, response, authentication) -> {
            AdminUser loginUser = (AdminUser) authentication.getPrincipal();
            Token token = adminTokenService.saveToken(loginUser);
            CookieUtil.setCookie(response, "token", token.getToken());
            ResponseUtil.responseRedirectUrl(response, "/backstage/product/listPageProducts");
        };
    }


    /**
     * 登陆失败
     *
     * @return org.springframework.security.web.authentication.AuthenticationFailureHandler
     * @author 石一歌
     * @date 2022/8/9 23:36
     */
    @Bean
    public AuthenticationFailureHandler loginFailureHandler() {
        return (request, response, exception) -> {
            BaseResponse<?> info;
            log.error("", exception);
            if (exception instanceof BadCredentialsException) {
                info = BaseResponse.error(ErrorMessage.LOGIN_ERROR_USERNAME_PASSWORD_ERROR);
            } else if (exception.getCause() instanceof BaseAuthenticationException) {
                BaseAuthenticationException e = (BaseAuthenticationException) exception.getCause();
                info = e.resp();
            } else if (exception instanceof BaseAuthenticationException) {
                BaseAuthenticationException e = (BaseAuthenticationException) exception;
                info = e.resp();
            } else if (exception instanceof DisabledException) {
                info = BaseResponse.error(ErrorMessage.ACCOUNT_DISABLE);
            } else {
                info = BaseResponse.error(ErrorMessage.LOGIN_ERROR);
            }

            ResponseUtil.responseJson(request, response, HttpStatus.OK.value(), info);
        };
    }

    /**
     * 退出处理
     *
     * @return org.springframework.security.web.authentication.logout.LogoutSuccessHandler
     * @author 石一歌
     * @date 2022/8/9 23:36
     */
    @Bean
    public LogoutSuccessHandler logoutSussHandler() {
        return (request, response, authentication) -> {
            String token = TokenFilter.getToken(request);
            adminTokenService.deleteToken(token);
            ResponseUtil.responseRedirectUrl(response, "/backstage/public/beforeLogin");
        };

    }

    /**
     * 解决匿名用户访问无权限资源时的异常
     *
     * @return org.springframework.security.web.AuthenticationEntryPoint
     * @author 石一歌
     * @date 2022/8/9 23:23
     */
    @Bean
    public AuthenticationEntryPoint authenticationEntryPoint() {
        return (request, response, authException) -> {
            log.error("", authException);
            BaseResponse<?> resp = BaseResponse.error(ErrorMessage.NO_LOGIN);
            ResponseUtil.responseJson(request, response, HttpStatus.OK.value(), resp);
        };
    }

    /**
     * 认证过的用户访问无权限资源时的异常
     *
     * @return org.springframework.security.web.access.AccessDeniedHandler
     * @author 石一歌
     * @date 2022/8/9 23:23
     */
    @Bean
    public AccessDeniedHandler accessDeniedHandler() {
        return (request, response, accessDeniedException) -> {
            log.error("", accessDeniedException);
            BaseResponse<?> resp = BaseResponse.error(ErrorMessage.USER_NO_PERMISSION);
            ResponseUtil.responseJson(request, response, HttpStatus.OK.value(), resp);
        };
    }

}
